package cn.raven.basic.service.impl;

import cn.raven.basic.constant.BaseConstant;
import cn.raven.basic.dto.VerifyRegisterDto;
import cn.raven.basic.exception.BusinessException;
import cn.raven.basic.service.IVerifyCodeService;
import cn.raven.basic.utils.StrUtils;
import cn.raven.basic.utils.VerifyCodeUtils;
import cn.raven.user.domain.User;
import cn.raven.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    /**
    * @Title: captcha
    * @Description: 生成图形验证码
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 19:20
    * @Parameters: [imageCodeKey]
    * @Return java.lang.String
      */
    @Override
    public String captcha(String imageCodeKey) {
        //校验参数不能为空
        if (StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("必要参数不能为空");
        }
        //获取四位的验证码
        String code = StrUtils.getComplexRandomString(1);
        //用工具类转成base64
        String imgCodeBase64 = VerifyCodeUtils.VerifyCode(100, 30, code);
        //保存到 redis中，设置有效期五分钟
        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
        return imgCodeBase64;
    }
    /**
    * @Title: smsCode
    * @Description: 发送短信验证码
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/6 19:21
    * @Parameters: [verifyRegisterDto]
    * @Return void
      */
    @Override
    public void smsCode(VerifyRegisterDto verifyRegisterDto) {
        //获取参数
        String phone = verifyRegisterDto.getPhone();

        String type = verifyRegisterDto.getType();
        //非空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)){
            throw new BusinessException("参数不能为空!");
        }
        //判断业务类型
        if ("register".equals(type)){
            //校验图形验证码
            imageCode(verifyRegisterDto);
            //手机号是否注册
            User user = userMapper.findByPhone(phone);
            if (user != null){
                throw new BusinessException("手机号已被注册,请直接登录");
            }
            //发送短信验证码
            sendCode(BaseConstant.BusinessConstant.SMS_REGISTER_CODE,phone);
        }else if ("binder".equals(type)){
            //发送短信验证码
            sendCode(BaseConstant.BusinessConstant.SMS_BINDER_CODE,phone);
        }
    }
    
    /** 
    * @Title: imageCode
    * @Description: 校验图形验证码
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/10 17:24  
    * @Parameters: [verifyRegisterDto]
    * @Return void
      */
    public void imageCode(VerifyRegisterDto verifyRegisterDto){
        String imageCodeValue = verifyRegisterDto.getImageCodeValue();
        String imageCodeKey = verifyRegisterDto.getImageCodeKey();
        //非空
        if (StringUtils.isEmpty(imageCodeValue) || StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("参数不能为空!");
        }

        Object imageCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
        //验证图形码校验
        if (imageCodeTmp == null){
            throw new BusinessException("验证码已过期");
        }

        if (!imageCodeTmp.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinessException("图形验证码错误,请重写输入");
        }
    }

    /**
    * @Title: sendCode
    * @Description: 发送短信验证码
    * @Author: king
    * @Version: 1.0
    * @Date:  2022/7/10 17:22
    * @Parameters: [codeKey, phone]
    * @Return void
      */
    public void sendCode(String codeKey,String phone){
        //业务键+电话号生成Redis中的key
        String smsCodeKey = codeKey + phone;
        //获取redis中对应的验证码
        Object smsCodeValue = redisTemplate.opsForValue().get(smsCodeKey);
        //保存验证码
        String phoneCode = "";
        //如果redis没有验证码
        if (smsCodeValue ==null){//生成验证码
            phoneCode = StrUtils.getComplexRandomString(4);

        }else {//如果有
            String[] smsSplit = smsCodeValue.toString().split(":");
            Long oldTime = Long.valueOf(smsSplit[0]);
            Long nowTime = System.currentTimeMillis();
            //当前时间戳减去存在验证码的时间戳，小于一分钟
            if (nowTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟后点击获取");
            }
            //直接使用当前验证码
            phoneCode = smsSplit[1];
        }
        String phoneCodeReal = System.currentTimeMillis()+":"+phoneCode;
        //将验证码保存到redis
        redisTemplate.opsForValue().set(smsCodeKey,phoneCodeReal,3,TimeUnit.MINUTES);
        //发短信
        System.out.println("你丫的验证码是："+ phoneCode);
    }
}
